package com.gitee.empty_null.spark;

import com.gitee.empty_null.context.SparkChatContextHolder;
import com.gitee.empty_null.context.SparkChatDomain;
import com.gitee.empty_null.properties.SparkChatProperties;
import com.gitee.empty_null.properties.SparkChatProperty;
import lombok.Getter;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.WebSocket;
import org.springframework.http.codec.ServerSentEvent;
import reactor.core.publisher.FluxSink;

import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

/**
 * @author xuhainan
 * @date 2023/11/17 17:26
 * @region hefei
 */
public record SparkChatClient(SparkChatProperties chatProperties) {

    private static final Map<SparkChatDomain, String> CHAT_DOMAIN_URL_MAP = new HashMap<>();

    public SparkChatClient(SparkChatProperties chatProperties) {
        this.chatProperties = chatProperties;
        SparkChatContextHolder.addAll(chatProperties.getProperties());
        Optional.ofNullable(chatProperties.getHostUrl())
                .ifPresent(request -> CHAT_DOMAIN_URL_MAP.put(SparkChatDomain.V1, request));
        Optional.ofNullable(chatProperties.getHostUrl2())
                .ifPresent(request -> CHAT_DOMAIN_URL_MAP.put(SparkChatDomain.V2, request));
        Optional.ofNullable(chatProperties.getHostUrl3())
                .ifPresent(request -> CHAT_DOMAIN_URL_MAP.put(SparkChatDomain.V3, request));
    }

    public WebSocket newInstance(FluxSink<ServerSentEvent<String>> sink, SparkChatDomain domain) throws Exception {
        return newInstance(sink, null, domain);
    }

    public WebSocket newInstance(FluxSink<ServerSentEvent<String>> sink, String event, SparkChatDomain domain) throws Exception {
        String url = CHAT_DOMAIN_URL_MAP.get(domain);
        Request request = Optional.ofNullable(initRequest(url)).orElseThrow(() -> new RuntimeException("客戶端初始化失败"));
        OkHttpClient client = new OkHttpClient.Builder().build();
        return client.newWebSocket(request, new SparkChatListener(sink, event));
    }

    private Request initRequest(String hostUrl) {
        SparkChatProperty property = SparkChatContextHolder.get();
        String apiKey = property.getApiKey();
        String apiSecret = property.getApiSecret();
        String authUrl;
        try {
            authUrl = SparkBase.create()
                    .setHostUrl(hostUrl)
                    .setApiKey(apiKey)
                    .setApiSecret(apiSecret)
                    .auth();
        } catch (Exception e) {
            return null;
        }
        return new Request.Builder().url(authUrl).build();
    }
}
